package com;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.util.excel.FileUtilH;
import com.util.excel.Listener;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;

import java.io.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * @Description: TODO
 * @Author: hechaobo
 * @Date: 2023/9/15
 **/
@Slf4j
public class Util {

    /**
     * 获取对象所有属性
     *
     * @param o
     * @return
     */
    public static List getObjectValue(Object o) {

        Field[] declaredFields = o.getClass().getDeclaredFields();
        int n = declaredFields.length;
        List res = new ArrayList();
        for (int i = 0; i < n; i++) {
            try {
                declaredFields[i].setAccessible(true);
                res.add(declaredFields[i].get(o));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return res;
    }

    /**
     * 设置对象属性
     *
     * @param o
     * @param values
     */
    public static void setObjectValue(Object o, Object[] values) {
        Field[] declaredFields = o.getClass().getDeclaredFields();
        int n = declaredFields.length;
        for (int i = 0; i < n; i++) {
            try {
                declaredFields[i].setAccessible(true);
                declaredFields[i].set(o, values[i]);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    public static List<String> getNullValues(Object o) {
        List<String> list = new ArrayList<String>();
        Field[] declaredFields = o.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            try {
                if (field.get(o) == null) {
                    list.add(field.getName());
                } else {
                    if (field.get(o) instanceof String) {
                        if (((String) field.get(o)).length() == 0) {
                            list.add(field.getName());
                        }
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

    public static List<File>  unzipInputStream(InputStream zipInputStream) {
        List<File> fileList = new ArrayList<>();
        try (ZipArchiveInputStream zip = new ZipArchiveInputStream(zipInputStream)) {
            ZipArchiveEntry zipEntry = null;
            while ((zipEntry = zip.getNextZipEntry()) != null) {
                String fileName_zip = zipEntry.getName();
                File file = new File(fileName_zip);
                if (fileName_zip.endsWith("/")) {
                    file.mkdir();
                    continue;
                } else {
                    BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file));
                    byte[] byte_s = new byte[1024];
                    int num;
                    while ((num = zip.read(byte_s, 0, byte_s.length)) > 0) {
                        outputStream.write(byte_s, 0, num);
                    }
                    outputStream.close();
                }
                fileList.add(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileList;
    }


    /**
     * 根据map设值
     *
     * @param data     数据
     * @param map      地图
     * @param getKey   获取密钥
     * @param setValue 设定值
     */
    public static  <T> void setFiledByMap(List<T> data, Map<String,String> map,
                                          Function<T,String> getKey, BiConsumer<T,String> setValue){
        for (T datum : data) {
            String s = map.get(getKey.apply(datum));
            if(s != null){
                setValue.accept(datum,s);
            }
        }
    }


    public static String join(String s, Collection<String> collection) {
        return collection.stream().collect(Collectors.joining(s));
    }


    /**
     * 合并map
     * 将map2的值合并到map1中
     *
     * @param map1
     * @param map2
     * @return
     */
    public static Map<String, List> mergeMap(Map<String, List> map1, Map<String, List> map2) {
        for (Map.Entry<String, List> entry : map1.entrySet()) {
            String key = entry.getKey();
            List c = map2.get(key);
            if (c == null) continue;
            entry.getValue().addAll(c);
        }
        return map1;
    }

    public static Date getOffsetMonth() {
        return DateUtil.offsetMonth(new Date(), -1);
    }

    /**
     * 获取字段下标
     *
     * @param name
     * @param cls
     * @return
     */
    public static Map<String, Integer> getFiledIndex(String name, Class cls) {
        Map<String, Integer> map = new HashMap<String, Integer>();
        Field[] declaredFields = cls.getDeclaredFields();
        for (int i = 0; i < declaredFields.length; i++) {
            map.put(declaredFields[i].getName(), i);
        }
        return map;
    }

    /**
     * 转置列表，行和列对调
     *
     * @param lists
     * @return
     */
    public static List<List> transpositionList(List<List> lists) {
        List<List> list = new LinkedList<>();
        int size = lists.get(0).size();
        for (int i = 0; i < size; i++) {
            list.add(new LinkedList());
        }
        for (List list1 : lists) {
            for (int i = 0; i < size; i++) {
                list.get(i).add(list1.get(i));
            }
        }
        return list;
    }

    /**
     * @return 当前日期
     */
    public static String getDateYYYYMMdd() {
        return DateUtil.date().toString("YYYY-MM-dd");
    }

    /**
     * 判断是否是中文字符
     *
     * @param c
     * @return
     */
    public static boolean isChinese(char c) {
        return c >= '\u4e00' && c <= '\u9fa5';
    }



}
